package cn.unknowpupil.init.controller.system;

import cn.unknowpupil.init.common.constant.SecurityConstants;
import cn.unknowpupil.init.common.enums.BusinessType;
import cn.unknowpupil.init.common.resopnse.ResultResponse;
import cn.unknowpupil.init.common.service.TokenService;
import cn.unknowpupil.init.components.annotation.Log;
import cn.unknowpupil.init.components.annotation.RunTime;
import cn.unknowpupil.init.domain.dto.LoginUser;
import cn.unknowpupil.init.domain.dto.SysUserDto;
import cn.unknowpupil.init.domain.system.SysUser;
import cn.unknowpupil.init.service.system.ISysUserService;
import cn.unknowpupil.init.utils.ExcelUtil;
import cn.unknowpupil.init.utils.SecurityUtils;
import cn.unknowpupil.init.utils.ServletUtils;
import cn.unknowpupil.init.utils.StringUtils;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.google.common.collect.Maps;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.Valid;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * Created at 2020-10-16 by  w10g <br>
 * Initialize SysUser  ... <br>
 * 管理员信息表 视图浏览层处理
 *
 * @author unknowpupil
 * @since 0.0.1
 */
@Api(tags = {"系统-管理员信息表模块"}, value = "sys-user")
@RestController
@RequestMapping(value = "admin/sys-user")
@RequiredArgsConstructor
public class SysUserController {


    private final ISysUserService sysUserService;
    private final TokenService tokenService;
    private final BCryptPasswordEncoder bCryptPasswordEncoder;

    /**
     * 新增
     *
     * @param SysUser {@link SysUser}  用户信息表
     * @return {@link ResultResponse}
     */
    @ApiOperation("系统：新增")
    @Log(title = "新增用户", businessType = BusinessType.INSERT)
    @PostMapping("create")
    public ResultResponse create(@Valid @RequestBody SysUser SysUser, BindingResult bindingResult) {
        // 表单验证
        if (bindingResult.hasErrors()) {
            return ResultResponse.buildFailure(Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage());
        }
        LoginUser user = SecurityUtils.getLoginUser();
        if(!SecurityUtils.isAdmin(user.getId())&&!SecurityUtils.isAdmin(user.getPid())){
            return ResultResponse.buildFailure("您没有权限创建用户");
        }

        // 业务逻辑
        boolean created = sysUserService.create(SysUser);
        if (created) {
            return ResultResponse.success("创建成功");
        } else {
            return ResultResponse.buildFailure("创建失败");
        }

    }

    /**
     * 修改
     *
     * @param SysUser {@link SysUser}  用户信息表
     * @return {@link ResultResponse}
     */
    @Log(title = "修改用户", businessType = BusinessType.UPDATE)
    @PutMapping("update")
    public ResultResponse update(@Validated @RequestBody SysUser SysUser) {

        // 业务逻辑
        boolean update = sysUserService.update(SysUser);
        if (update) {
            return ResultResponse.success("修改成功");
        } else {
            return ResultResponse.buildFailure("修改失败");
        }

    }


    /**
     * 根据用户编号获取详细信息
     */
    @ApiOperation("系统：查询用户")
    @GetMapping(value = {"get/", "get/{userId}"})
    public ResultResponse getInfo(@PathVariable(value = "userId", required = false) Long userId) {
        SysUser byId = sysUserService.getById(userId);
        return ResultResponse.buildSuccess(byId);
    }

    /**
     * 删除
     *
     * @param ids {@code Long}
     * @return {@link ResultResponse}
     */
    @ApiOperation("系统：删除用户")
    @Log(title = "删除用户", businessType = BusinessType.DELETE)
    @DeleteMapping("remove/{ids}")
    public ResultResponse remove(@PathVariable("ids") Long[] ids) {
        // 业务逻辑
        boolean deleted = sysUserService.delete(ids);

        if (deleted) {

            return ResultResponse.success("删除成功");

        } else {
            return ResultResponse.buildFailure("删除失败");
        }
    }

    /**
     * 分页
     *
     * @param current {@code int} 页码
     * @param size    {@code int} 笔数
     * @return {@link ResultResponse}
     */
    @ApiOperation("系统：分页查询用户")
    @GetMapping("page/{current}/{size}")
    public ResultResponse<IPage<SysUser>> page(@PathVariable("current") int current, @PathVariable("size") int size, @ModelAttribute SysUser SysUser) {

        IPage<SysUser> page = sysUserService.page(current, size, SysUser);
        return ResultResponse.buildSuccess(page);
    }

    /**
     * 分页
     *
     * @param current {@code int} 页码
     * @param size    {@code int} 笔数
     * @return {@link ResultResponse}
     */
    @ApiOperation("系统：子用户分页查询")
    @Log(title = "子用户分页查询", businessType = BusinessType.OTHER)
    @GetMapping("pages/{current}/{size}")
    public ResultResponse<IPage<SysUser>> pages(@PathVariable("current") int current, @PathVariable("size") int size, @ModelAttribute SysUser SysUser) {

        if(SysUser.getPId()==null){
            if(!SecurityUtils.isSuperAdmin(SecurityUtils.getLoginUser().getPid())){{
                return ResultResponse.buildFailure("您没有权限访问");
            }}
            SysUser.setPId(SecurityUtils.getLoginUser().getId());
        }else {
            if(!SecurityUtils.isSuperAdmin(SecurityUtils.getLoginUser().getPid())&&!SecurityUtils.isAdmin(SecurityUtils.getLoginUser().getPid())){
                return ResultResponse.buildFailure("您没有权限访问");
            }
        }

        IPage<SysUser> page = sysUserService.page(current, size, SysUser);
        return ResultResponse.buildSuccess(page);
    }

    @ApiOperation("系统：重置密码")
    @Log(title = "重置用户密码", businessType = BusinessType.UPDATE)
    @PutMapping("change/password")
    public ResultResponse<IPage<SysUser>> changePwd(@RequestBody SysUser user) {
        boolean b = sysUserService.changePwd(user);
        if (b) {
            return ResultResponse.success("修改密码成功");
        } else {
            return ResultResponse.buildFailure("修改密码失败");
        }
    }


    @ApiOperation("系统：修改状态")
    @Log(title = "修改用户状态", businessType = BusinessType.UPDATE)
    @PutMapping("change/status")
    public ResultResponse<IPage<SysUser>> changeStatus(@RequestBody SysUser user) {
        boolean b = sysUserService.changeStatus(user);
        if (b) {
            return ResultResponse.success("修改状态成功");
        } else {
            return ResultResponse.buildFailure("修改状态失败");
        }
    }

    @ApiOperation("系统：个人信息")
    @GetMapping("profile")
    public ResultResponse profile() {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        SysUser user = sysUserService.getById(loginUser.getId());
        Map<String, Object> map = Maps.newHashMap();
        map.put("user", user);
        return ResultResponse.buildSuccess(map);

    }

    @ApiOperation("系统：个人信息")
    @Log(title = "修改用户个人信息", businessType = BusinessType.UPDATE)
    @PutMapping("profile")
    public ResultResponse editProfile(@RequestBody SysUser sysUser) {
        boolean user = sysUserService.editProfile(sysUser);
        if (user) {
            LoginUser loginUser = SecurityUtils.getLoginUser();
            // 更新缓存用户信息
            loginUser.setUsername(sysUser.getUserName());
            tokenService.refreshToken(loginUser);
            return ResultResponse.success("修改成功");
        }
        return ResultResponse.buildFailure("修改个人信息异常，请联系管理员");

    }

    /**
     * 重置密码
     */
    @Log(title = "修改用户密码", businessType = BusinessType.UPDATE)
    @PutMapping("profile/reset/password")
    public ResultResponse updatePwd(String oldPassword, String newPassword) {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        String password = loginUser.getPassword();
        boolean matches = bCryptPasswordEncoder.matches(oldPassword, password);
        if (!matches) {
            return ResultResponse.buildFailure("修改密码失败，旧密码错误");
        }
        matches = bCryptPasswordEncoder.matches(newPassword, password);

        if (matches) {
            return ResultResponse.buildFailure("新密码不能与旧密码相同");
        }
        SysUser user = new SysUser();
        user.setId(loginUser.getId());
        user.setPassword(newPassword);

        if (sysUserService.changePwd(user)) {
            // 更新缓存用户密码
            loginUser.setPassword(bCryptPasswordEncoder.encode(newPassword));
            tokenService.refreshToken(loginUser);
            return ResultResponse.success("修改成功");
        }
        return ResultResponse.buildFailure("修改密码异常，请联系管理员");
    }






    @Log(title = "用户头像", businessType = BusinessType.UPDATE)
    @PostMapping("profile/avatar")
    @ApiOperation("用户头像")
    public ResultResponse upload(@RequestParam("avatarFile") MultipartFile avatarFile) throws IOException {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        String path = sysUserService.updateAvatar(avatarFile, loginUser.getId());
        return ResultResponse.buildSuccess(path);

    }




    @Log(title = "导入用户", businessType = BusinessType.INSERT)
    @PostMapping("import_data")
    @ApiOperation("导入用户")
    public ResultResponse importData(MultipartFile file, boolean updateSupport) throws Exception {
        LoginUser user = SecurityUtils.getLoginUser();
        if(!SecurityUtils.isSuperAdmin(user.getPid())&&!SecurityUtils.isAdmin(user.getPid())){
            return ResultResponse.buildFailure("您没有权限导入用户");
        }
        ExcelUtil<SysUserDto> util = new ExcelUtil<SysUserDto>(SysUserDto.class);
        List<SysUserDto> userList = util.importExcel(file.getInputStream());
        System.err.println("导入用户"+userList);
        LoginUser loginUser = SecurityUtils.getLoginUser();
        String message = sysUserService.importUser(userList, updateSupport, loginUser);
        return ResultResponse.success(message);

    }


}
